package net.oschina.gitapp.ui.basefragment;

import java.util.ArrayList;
import java.util.List;
import net.oschina.gitapp.AppContext;
import net.oschina.gitapp.R;
import net.oschina.gitapp.bean.Entity;
import net.oschina.gitapp.bean.MessageData;
import net.oschina.gitapp.bean.PageList;
import net.oschina.gitapp.common.DataRequestThreadHandler;
import net.oschina.gitapp.widget.NewDataToast;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

/**
 * 说明 下拉刷新界面的基类
 */
public abstract class BaseSwipeRefreshFragment<Data extends Entity, Result extends PageList<Data>>
        extends BaseFragment implements SwipeRefreshLayout.OnRefreshListener,
        OnItemClickListener, OnScrollListener {
    
    // 没有状态
    public static final int LISTVIEW_ACTION_NONE = -1;
    // 更新状态，不显示toast
    public static final int LISTVIEW_ACTION_UPDATE = 0;
    // 初始化时，加载缓存状态
    public static final int LISTVIEW_ACTION_INIT = 1;
    // 刷新状态，显示toast
    public static final int LISTVIEW_ACTION_REFRESH = 2;
    // 下拉到底部时，获取下一页的状态
    public static final int LISTVIEW_ACTION_SCROLL = 3;
    
    static final int STATE_NONE = -1;
    static final int STATE_LOADING = 0;
    static final int STATE_LOADED = 1;
    
    protected AppContext mApplication;
    
    protected SwipeRefreshLayout mSwipeRefreshLayout;
    protected ListView mListView;
    private View mHeaderView;
    private View mFooterView;
    private BaseAdapter mAdapter;
    private ProgressBar mLoading;
    private View mEmpty;
    private ImageView mEmptyImage;// 图像
    private TextView mEmptyMessage;// 消息文字
    
    private View mFooterProgressBar;
    private TextView mFooterTextView;
    
    private List<Data> mDataList = new ArrayList<Data>();
    // 当前页面已加载的数据总和
    private int mSumData;
    
    // 当前加载状态
    private int mState = STATE_NONE;
    // UI状态
    private int mListViewAction = LISTVIEW_ACTION_NONE;
    
    // 当前数据状态，如果是已经全部加载，则不再执行滚动到底部就加载的情况
    private int mMessageState = MessageData.MESSAGE_STATE_MORE;
    private boolean isPauseLife = true;
    
    private DataRequestThreadHandler mRequestThreadHandler = new DataRequestThreadHandler();
    
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mApplication = getGitApplication();
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAdapter = getAdapter(mDataList);
    }
    
    @Override
    public void onPause() {
        super.onPause();
        isPauseLife = true;
    }
    
    @Override
    public void onResume() {
        super.onResume();
        isPauseLife = false;
    }
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        mRequestThreadHandler.quit();
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mHeaderView = getHeaderView(inflater);
        mFooterView = inflater.inflate(R.layout.listview_footer, null);
        mFooterProgressBar = mFooterView
                .findViewById(R.id.listview_foot_progress);
        mFooterTextView = (TextView) mFooterView
                .findViewById(R.id.listview_foot_more);
        
        return inflater.inflate(R.layout.fragment_base_swiperefresh, null);
    }
    
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        
        initView(view);
        setupListView();
        
        // viewpager划动到第三页，会将第一页的界面销毁，这里判断是初始状态，还是划画后再次加载
        if (mState == STATE_LOADED && mAdapter.isEmpty()) {
            setFooterNoMoreState();
        }
        else if (mState == STATE_LOADED
                && mAdapter.getCount() < AppContext.PAGE_SIZE) {
            setFooterFullState();
        }
        // 正在刷新的状态
        if (mListViewAction == LISTVIEW_ACTION_REFRESH) {
            setSwipeRefreshLoadingState();
        }
        loadList(1, LISTVIEW_ACTION_INIT);
    }
    
    private void initView(View view) {
        mSwipeRefreshLayout = (SwipeRefreshLayout) view
                .findViewById(R.id.fragment_swiperefreshlayout);
        mListView = (ListView) view.findViewById(R.id.fragment_listview);
        
        mSwipeRefreshLayout.setOnRefreshListener(this);
        mSwipeRefreshLayout.setColorScheme(R.color.swiperefresh_color1,
                R.color.swiperefresh_color2, R.color.swiperefresh_color3,
                R.color.swiperefresh_color4);
        
        mLoading = (ProgressBar) view
                .findViewById(R.id.fragment_swiperefresh_loading);
        mEmpty = view.findViewById(R.id.fragment_swiperefresh_empty);
        mEmptyImage = (ImageView) mEmpty.findViewById(R.id.data_empty_image);
        mEmptyMessage = (TextView) mEmpty.findViewById(R.id.data_empty_message);
    }
    
    /** 设置列表空数据时的显示信息 */
    public void setEmptyInfo(int imageResId, int messageResId) {
        mEmptyImage.setBackgroundResource(imageResId);
        mEmptyMessage.setText(messageResId);
    }
    
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
    }
    
    /** 获取HeaderView */
    protected View getHeaderView(LayoutInflater inflater) {
        return null;
    }
    
    /** 初始化ListView */
    protected void setupListView() {
        mListView.setOnScrollListener(this);
        mListView.setOnItemClickListener(this);
        mListView.addFooterView(mFooterView);
        mListView.setAdapter(mAdapter);
        if (mHeaderView != null) {
            mListView.addHeaderView(mHeaderView);
        }
    }
    
    /** 获取适配器 */
    public abstract BaseAdapter getAdapter(List<Data> list);
    
    /** 异步加载数据 */
    protected abstract MessageData<Result> asyncLoadList(int page,
            boolean reflash);
    
    @Override
    public void onRefresh() {
        loadList(1, LISTVIEW_ACTION_REFRESH);
    }
    
    /** 更新数据，不显示toast */
    public void update() {
        loadList(1, LISTVIEW_ACTION_UPDATE);
    }
    
    /** 返回是否正在加载 */
    public boolean isLoadding() {
        return mState == STATE_LOADING;
    }
    
    /** 加载下一页 */
    protected void onLoadNextPage() {
        // 当前pageIndex
        int pageIndex = mSumData / AppContext.PAGE_SIZE + 1;
        loadList(pageIndex, LISTVIEW_ACTION_SCROLL);
    }
    
    /**
     * 加载数据
     * 
     * @param page
     *            页码
     * @param action
     *            加载的触发事件
     * */
    void loadList(int page, int action) {
        mListViewAction = action;
        mRequestThreadHandler.request(page, new AsyncDataHandler(page, action));
    }
    
    /** 设置顶部正在加载的状态 */
    void setSwipeRefreshLoadingState() {
        if (mSwipeRefreshLayout != null) {
            mSwipeRefreshLayout.setRefreshing(true);
            // 防止多次重复刷新
            mSwipeRefreshLayout.setEnabled(false);
        }
        onRefreshLoadingStatus();
    }
    
    /** 设置顶部加载完毕的状态 */
    void setSwipeRefreshLoadedState() {
        if (mSwipeRefreshLayout != null) {
            mSwipeRefreshLayout.setRefreshing(false);
            mSwipeRefreshLayout.setEnabled(true);
        }
        onRefreshLoadedStatus();
    }
    
    /** 设置底部有错误的状态 */
    void setFooterErrorState() {
        if (mFooterView != null) {
            mFooterProgressBar.setVisibility(View.GONE);
            mFooterTextView.setText(R.string.load_error);
        }
    }
    
    /** 设置底部有更多数据的状态 */
    void setFooterHasMoreState() {
        if (mFooterView != null) {
            mFooterProgressBar.setVisibility(View.GONE);
            mFooterTextView.setText(R.string.load_more);
        }
    }
    
    /** 设置底部已加载全部的状态 */
    void setFooterFullState() {
        if (mFooterView != null) {
            mFooterProgressBar.setVisibility(View.GONE);
            mFooterTextView.setText(R.string.load_full);
        }
    }
    
    /** 设置底部无数据的状态 */
    void setFooterNoMoreState() {
        if (mFooterView != null) {
            mFooterProgressBar.setVisibility(View.GONE);
            mFooterTextView.setText(R.string.load_empty);
        }
    }
    
    /** 设置底部加载中的状态 */
    void setFooterLoadingState() {
        if (mFooterView != null) {
            mFooterProgressBar.setVisibility(View.VISIBLE);
            mFooterTextView.setText(R.string.load_ing);
        }
    }
    
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
        // 点击了底部
        if (view == mFooterView) {
            return;
        }
        // 点击了顶部
        if (mHeaderView == view) {
            return;
        }
        if (mHeaderView != null) {
            position = position - 1;
        }
        Data data = getData(position);
        onItemClick(position, data);
    }
    
    /** 点击了某个item */
    public void onItemClick(int position, Data data) {
    }
    
    /** 正在加载的状态 */
    public void onRefreshLoadingStatus() {
    }
    
    /** 加载完毕的状态 */
    public void onRefreshLoadedStatus() {
    }
    
    /**
     * 返回某项的数据
     * 
     * @param position
     *            数据位置
     * */
    public Data getData(int position) {
        return mDataList.get(position);
    }
    
    public void beforeLoading(int action) {
        // 开始加载
        mState = STATE_LOADING;
        if (action == LISTVIEW_ACTION_REFRESH) {
            setSwipeRefreshLoadingState();
        }
        else if (action == LISTVIEW_ACTION_SCROLL) {
            setFooterLoadingState();
        }
    }
    
    public void afterLoading() {
        
    }
    
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (mAdapter == null || mAdapter.getCount() == 0) {
            return;
        }
        // 数据已经全部加载，或数据为空时，或正在加载，不处理滚动事件
        if (mMessageState == MessageData.MESSAGE_STATE_FULL
                || mMessageState == MessageData.MESSAGE_STATE_EMPTY
                || mState == STATE_LOADING) {
            return;
        }
        // 判断是否滚动到底部
        boolean scrollEnd = false;
        try {
            if (view.getPositionForView(mFooterView) == view
                    .getLastVisiblePosition())
                scrollEnd = true;
        }
        catch (Exception e) {
            scrollEnd = false;
        }
        
        if (scrollEnd) {
            onLoadNextPage();
        }
    }
    
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
    }
    
    // 加载数据
    private class AsyncDataHandler implements
            DataRequestThreadHandler.AsyncDataHandler<MessageData<Result>> {
        
        private int mPage;
        private int mAction;
        
        AsyncDataHandler(int page, int action) {
            mAction = action;
            mPage = page;
        }
        
        @Override
        public void onPreExecute() {
            beforeLoading(mAction);
        }
        
        @Override
        public MessageData<Result> execute() {
            boolean refresh = true;
            if (mAction == LISTVIEW_ACTION_INIT) {
                refresh = false;
            }
            return asyncLoadList(mPage, refresh);
        }
        
        @Override
        public void onPostExecute(MessageData<Result> msg) {
            // 加载结束
            mState = STATE_LOADED;
            if (mAction == LISTVIEW_ACTION_INIT) {
                mSwipeRefreshLayout.setVisibility(View.VISIBLE);
                mLoading.setVisibility(View.GONE);
            }
            
            // 如果动作是下拉刷新，则将刷新中的状态去掉
            if (mAction == LISTVIEW_ACTION_REFRESH) {
                setSwipeRefreshLoadedState();
            }
            // 更新全局的状态
            if (mListViewAction == mAction) {
                mListViewAction = LISTVIEW_ACTION_NONE;
            }
            
            // 无数据的情况下(已经加载全部数据，与一开始没有数据)
            if (msg.state == MessageData.MESSAGE_STATE_EMPTY
                    && mDataList.size() != 0) {
                msg.state = MessageData.MESSAGE_STATE_FULL;
            }
            if (msg.result != null && msg.result.getList().size() == 0) {
                msg.state = MessageData.MESSAGE_STATE_EMPTY;
            }
            // 记录最后的数据状态
            mMessageState = msg.state;
            
            if (msg.state == MessageData.MESSAGE_STATE_EMPTY) {
                // 底部显示“暂无数据”
                setFooterNoMoreState();
                return;
            }
            else if (msg.state == MessageData.MESSAGE_STATE_ERROR) {
                setFooterErrorState();
                return;
            }
            else if (msg.state == MessageData.MESSAGE_STATE_FULL) {
                // 当页数少于要求的加载页数的时，可以判断是已经加载完，没有更多的数据
                setFooterFullState();
            }
            else if (msg.state == MessageData.MESSAGE_STATE_MORE) {
                // 有数据的情况下，底部显示“正在加载...”
                setFooterHasMoreState();
            }
            
            Result result = msg.result;
            if (mPage == 1) {
                int newdata = 0;
                mSumData = result.getPageSize();
                if (mAction == LISTVIEW_ACTION_REFRESH
                        || mAction == LISTVIEW_ACTION_UPDATE) {
                    if (mDataList.size() > 0) {
                        // 计算新增数据条数
                        for (Data data1 : result.getList()) {
                            boolean b = false;
                            for (Data data2 : mDataList) {
                                if (data1.getId().equalsIgnoreCase(
                                        data2.getId())) {
                                    b = true;
                                    break;
                                }
                            }
                            if (!b) {
                                newdata++;
                            }
                        }
                    }
                    else {
                        newdata = result.getPageSize();
                    }
                    if (mAction == LISTVIEW_ACTION_REFRESH && !isPauseLife) {
                        // 提示新添加的数据条数
                        if (newdata > 0) {
                            NewDataToast
                                    .makeText(
                                            getActivity(),
                                            getString(
                                                    R.string.new_data_toast_message,
                                                    newdata),
                                            mApplication.isAppSound()).show();
                        }
                        else {
                            NewDataToast.makeText(getActivity(),
                                    getString(R.string.new_data_toast_none),
                                    false).show();
                        }
                    }
                }
                // 先清除原有数据
                mDataList.clear();
                // 加入最新的数据
                mDataList.addAll(result.getList());
            }
            else {
                mSumData += result.getPageSize();
                if (mDataList.size() > 0) {
                    for (Data data1 : result.getList()) {
                        boolean b = false;
                        for (Data data2 : mDataList) {
                            if (data1.getId().equalsIgnoreCase(data2.getId())) {
                                b = true;
                                break;
                            }
                        }
                        if (!b) {
                            mDataList.add(data1);
                        }
                    }
                }
                else {
                    // 加入新增的数据
                    mDataList.addAll(result.getList());
                }
            }
            // 通知listview去刷新界面
            mAdapter.notifyDataSetChanged();
        }
    }
    
    // 清空数据
    public void clearData() {
        mDataList.clear();
        mAdapter.notifyDataSetChanged();
    }
}